home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include "ip.h"
- #include "icmp.h"
- #include "timer.h"
-
- #include "nettrace.h"
-
-
- #define noDEBUG
-
- static void pingtmo(TIMER);
- static int icmp_pingstate;
- static TIMER icmp_pingtm;
- static int pingseq;
- static PACKET *sent;
- static int snt_len;
- struct redent redtab[REDIRTABLEN];int rednext = 0;int holdback = 0;
- long icmp_counts[2] = {0L,0L};
-
- int icmp_init(void)
- {
- int i;
- if(!ip_open(IP_ICMP,icmp_handler,(int (*)(IP *))NULL)) return(FALSE);
- icmp_pingstate = PGWAITING;
- for(i=0; i< REDIRTABLEN; i++)
- redtab[i].dst_inaddr = 0L;
- return(TRUE);
- }
-
-
- int icmp_handler(PACKET *pkt,int len,INADDR fhost){register IP *ip;register struct ping *e;struct redirect *rd;struct destun *pdp;u_short osum;char *data1, *data2;int i;
- ip = ip_head(pkt); e = (struct ping *)ip_data(pkt); osum = e->pchksum; e->pchksum = 0; if(chksum((u_short *)e,len,0) != osum)
- { ip_free(pkt); return(FALSE); } e->pchksum = osum; icmp_counts[0]++;
- switch(e->ptype)
- { case ICMP_ECHOREQ: /* ping */ e->ptype = ICMP_ECHOREP; e->pchksum = 0; e->pchksum = chksum((u_short *)e,len,0); ip->src_inaddr = ip->dst_inaddr; ip->dst_inaddr = fhost; icmp_counts[1]++;
- i = ip_send(IP_ICMP, pkt, len, fhost); ip_free(pkt);
- return(i); case ICMP_DESTIN: pdp = (struct destun *)e; ip_dudemux(&pdp->dip); /* DDP - upcall handler */ break;
- case ICMP_SOURCEQ:
- holdback++; /* hold back data - dst busy */ break;
-
- case ICMP_REDIR: rd = (struct redirect *)e; for(i=0; i<REDIRTABLEN; i++) if(redtab[i].dst_inaddr == rd->rdip.dst_inaddr)
- { redtab[i].gw_inaddr = rd->rdgw; ip_free(pkt); return(TRUE); } redtab[rednext].dst_inaddr = rd->rdip.dst_inaddr; redtab[rednext].gw_inaddr = rd->rdgw; rednext++; if(rednext >= REDIRTABLEN) rednext = 0; break;
-
- case ICMP_ECHOREP: if(e->pseq != pingseq-1)
- { ip_free(pkt); return(FALSE); } data1 = ((ICMP_PACKET *)pkt)->icmp_data; data2 = ((ICMP_PACKET *)sent)->icmp_data; for(i=0; i < snt_len; i++) if(*data1++ != *data2++)
- { icmp_pingstate = PGBADDATA; ip_free(pkt); return(FALSE); } icmp_pingstate = PGSUCCESS; ip_free(pkt); break; case ICMP_TIMEX: break;
- case ICMP_PARAM: break;
- case ICMP_TIMEREQ: e->ptype = ICMP_TIMEREP; e->pchksum = 0;
- e->pchksum = chksum((u_short *)e, (int)sizeof(struct tstamp),0); ip->src_inaddr = ip->dst_inaddr; ip->dst_inaddr = fhost; icmp_counts[1]++;
- i = ip_send(IP_ICMP, pkt, (int)sizeof(struct tstamp), fhost); ip_free(pkt);
- return(i);
- case ICMP_INFO: break;
- } ip_free(pkt);
- return(TRUE);}
-
-
-
- int icmp_dstun(INADDR inaddr ,IP *ip,int type)
- {
- PACKET *p;register struct destun *d;int i;
- p = ip_alloc(512, 0); if(p == NULL) return 0;
- d = (struct destun *)ip_data(p); d->dtype = ICMP_DESTIN; d->dcode = type; for(i=0; i<(int)sizeof(IP)+8; i++) ((char *)&d->dip)[i] = ((char *)ip)[i]; d->dchksum = 0; d->dchksum = chksum((u_short *)d, (int)sizeof(struct destun),0); icmp_counts[1]++;
- i = ip_send(IP_ICMP, p, (int)sizeof(struct destun), inaddr);
- ip_free(p); return(i);}
-
- icmp_ping(INADDR fhost, int length){PACKET *p;register struct ping *e;register char *data;int i;
- p = ip_alloc(40, 0);
- if(p == NULL)
- { return PGNOSND; } e = (struct ping *)ip_data(p); e->ptype = ICMP_ECHOREQ; e->pcode = 0; e->pid = 0; e->pseq = pingseq++;
- /* Put 256 random numbers in the packet. */ data = ip_data(p) + ICMP_PKTSIZE; for(i=0; i<length; i++) *data++ = rand();
- /* Calculate the checksum */ e->pchksum = 0; if((ICMP_PKTSIZE+length)&1) *data = 0; e->pchksum = chksum((u_short *)e, (ICMP_PKTSIZE+length+1),0); icmp_pingstate = PGWAITING; sent = p; snt_len = length; icmp_pingtm = tm_alloc(); if(icmp_pingtm < 0)
- { ip_free(p); return(PGNOSND); } tm_set(tm_msec(ECHO_TIMEOUT), pingtmo, icmp_pingtm ); icmp_counts[1]++;
- if(ip_send(IP_ICMP, p, ICMP_PKTSIZE+length, fhost) <= 0)
- { tm_free(icmp_pingtm ); ip_free(p); return(PGNOSND); } while(icmp_pingstate == PGWAITING) net_demux(FALSE,DEMUX); tm_free(icmp_pingtm ); ip_free(p); sent = 0; return(icmp_pingstate);}
- static void pingtmo(TIMER tm)
- {
- if(icmp_pingtm == tm) icmp_pingstate = PGTMO;}